/*
 * Tag.cpp
 *
 *  Created on: 2010-6-11
 *      Author: guobc
 */

#include "Tag.h"

namespace HA {

string Tag::NO_END_TAG_NAMES[] = { "AREA", "BASE", "BASEFONT", "BR", "FRAME",
		"HR", "IMG", "INPUT", "LINK", "META", "PARAM", "" };

Tag::Tag() :
	mTagName(""), attr() {
}

Tag::Tag(const string& tagName) :
	mTagName(tagName), attr() {

}

bool Tag::hasEndTag() {
	if (!mTagName.empty() && !isEndTag()) {
		string* p = NO_END_TAG_NAMES;
		while (!p->empty()) {
			if (mTagName == *p) {
				return false;
			}
		}
	}

	/**
	 * Some tag has no close tag.
	 * We take the slash as a attribute of this tag.
	 * So if a tag has '/' attribute, it represents a tag with no close tag.
	 */
	string value = getAttribute("/");
	if (!value.empty()) {
		return false;
	}
	return true;
}

void Tag::setAttribute(const string& key, const string& value) {
	if (!key.empty()) {
		attr[key] = value;
	}
}

string Tag::getAttribute(const string& key) {
	if (attr.count(key) == 1) {
		return attr[key];
	}
	return "";
}

void Tag::removeAttribute(const string& key) {
	if (attr.count(key) == 1) {
		attr.erase(key);
	}
}

string Tag::toHTML() {
	if(mTagName.empty()){
		return "";
	}
	string sb = "";
	if (!isEndTag()) {
		sb += "<" + mTagName;
		if (attr.size() > 0) {
			sb += " ";
			Attribute::reverse_iterator iter;
			for (iter = attr.rbegin(); iter != attr.rend(); iter++) {
				sb += iter->first;
				sb += "=";
				sb += iter->second;
				if (iter != attr.rend()) {
					sb += " ";
				}
			}
		}
		sb += ">";
	} else {
		sb += "<" + mTagName + ">";
	}
	return sb;
}

}
